package com.maven.front.util;


import org.apache.commons.lang3.time.FastDateFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;


/**
 * @Auther: huangjie
 * @date: $ $
 */
public class DateUtils {
    public static final String DATE_FORMAT = "yyyyMMddHHmmssSSS";
    public static final String DATE_FORMAT_YMDHMS_ = "yyyyMMddHHmmss";
    public static final String DATE_FORMAT_YMDHMS = "yyyyMMddHHmm";
    public static final String YMDHMS_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String YMDHM_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String YMD_FORMAT = "yyyy-MM-dd";
    public static final String YMD_POINT_FORMAT = "yyyy.MM.dd";
    private static final String YMDFORMAT = "yyyyMMdd";
    private static final String HMFORMAT = "HH:mm";
    public static FastDateFormat dateFastFormat = FastDateFormat.getInstance(DATE_FORMAT);
    public static FastDateFormat ymdhmsFastFormat = FastDateFormat.getInstance(YMDHMS_FORMAT);
    public static FastDateFormat ymdhmFastFormat = FastDateFormat.getInstance(YMDHM_FORMAT);
    public static FastDateFormat DATEFASTFORMAT_YMDHMS = FastDateFormat.getInstance(DATE_FORMAT_YMDHMS);
    public static FastDateFormat DATEFASTFORMAT_YMDHMS_ = FastDateFormat.getInstance(DATE_FORMAT_YMDHMS_);

    private static FastDateFormat ymdfastformat = FastDateFormat.getInstance(YMDFORMAT);
    private static FastDateFormat ymdFastFormat = FastDateFormat.getInstance(YMD_FORMAT);
    private static FastDateFormat YMD_FASTPOINTFORMAT = FastDateFormat.getInstance(YMD_POINT_FORMAT);
    private static FastDateFormat HM_FASTFORMAT = FastDateFormat.getInstance(HMFORMAT);

    public static Date getCurrentMonday() {
        int mondayPlus;
        Calendar cd = Calendar.getInstance();
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 1) {
            mondayPlus = 0;
        } else {
            mondayPlus = 1 - dayOfWeek;
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        currentDate.set(Calendar.HOUR_OF_DAY, 0);
        currentDate.set(Calendar.MINUTE, 0);
        currentDate.set(Calendar.SECOND, 0);
        Date monday = currentDate.getTime();
        return monday;
    }

    public static Date getNextMonday() {
        int mondayPlus;
        Calendar cd = Calendar.getInstance();
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 1) {
            mondayPlus = 0;
        } else {
            mondayPlus = 1 - dayOfWeek + 7;
        }
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        currentDate.set(Calendar.HOUR_OF_DAY, 0);
        currentDate.set(Calendar.MINUTE, 0);
        currentDate.set(Calendar.SECOND, 0);
        Date monday = currentDate.getTime();
        return monday;
    }

    public static Date getNextHalfOfYear() {
        return getAddMonth(6);
    }

    public static Date getAddMonth(int month) {

        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }

    public static Date getAddDay(int day) {

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, day);
        return c.getTime();
    }

    /**
     * 获取小时
     *
     * @param date
     * @return
     */
    public static String getHmHour(Date date) {
        String hour = HM_FASTFORMAT.format(date);
        return hour;
    }

    public static Date getAddMonthForDate(Date date, int month) {

        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }

    public static Date getAddDayForDate(Date date, int day) {

        Calendar c = Calendar.getInstance();
        if (date != null) {
            c.setTime(date);
        }
        c.add(Calendar.DAY_OF_YEAR, day);
        return c.getTime();
    }

    /**
     * 返回昨天
     *
     * @param today
     * @return
     */
    public static Date yesterday(Date today) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
        return calendar.getTime();
    }

    /**
     * 返回明天
     *
     * @param today
     * @return
     */
    public static Date tomorrow(Date today) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
        return calendar.getTime();
    }

    public static String getCurrentYMDPoint() {
        return YMD_FASTPOINTFORMAT.format(new Date());
    }

    public static String getYMDPoint(Date date) {
        return YMD_FASTPOINTFORMAT.format(date);
    }

    public static String getYMD(Date date) {
        return YMD_FASTPOINTFORMAT.format(date);
    }

    public static String getYMDHMSFormat(Date date) {
        return ymdhmsFastFormat.format(date);
    }

    public static String getYMDHMFormat(Date date) {
        return ymdhmFastFormat.format(date);
    }

    public static String getCurrFullTime() {
        return dateFastFormat.format(new Date());
    }

    public static String getCurrYMDHMSTime() {
        return DATEFASTFORMAT_YMDHMS.format(new Date());
    }

    public static String getCurrYMDHMSTime_() {
        return DATEFASTFORMAT_YMDHMS_.format(new Date());
    }

    public static Date getYmdHmsDate(String date) {
        try {
            return ymdhmsFastFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date getYmdDate(String date) {
        try {
            return ymdFastFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getCurrentYmd(Date date) {
        return ymdFastFormat.format(date);
    }

    public static String getCurrentYmd() {
        return ymdFastFormat.format(new Date());
    }

    public static String getCurrentYmdHMS() {
        return ymdhmsFastFormat.format(new Date());
    }

    public static String getYmdformat() {
        return ymdfastformat.format(new Date());
    }

    public static String getYmdformat(Date date) {
        return ymdfastformat.format(date);
    }

    public static String getYmdformats(Date date) {
        return ymdFastFormat.format(date);
    }

    /**
     * 判断session是否失效
     *
     * @param survivalTime
     * @param createdAt
     * @return
     */
    public static boolean isLoseTime(Integer survivalTime, Date createdAt) {
        if (survivalTime == 0) {
            return false;
        }
        Date _date = new Date(createdAt.getTime() + survivalTime * 1000);
        return _date.before(new Date());
    }

    /**
     * 获取日期格式为yyyyMMddHHmmss
     *
     * @return
     */
    public static String getDateStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(date);
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param date
     *            当前时间 yyyy-MM-dd HH:mm:ss
     * @param strDateBegin
     *            开始时间 00:00:00
     * @param strDateEnd
     *            结束时间 00:05:00
     * @return
     */
    public static boolean isInDate(Date date, String strDateBegin, String strDateEnd) {
        String nowdate = ymdFastFormat.format(date);
        strDateBegin = nowdate + " " + strDateBegin;
        strDateEnd = nowdate + " " + strDateEnd;
        long startTime = getYmdHmsDate(strDateBegin).getTime();
        long endTime = getYmdHmsDate(strDateEnd).getTime();
        if (date.getTime() >= startTime && date.getTime() <= endTime) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断时间是否在时间段内
     */
    public static boolean isInDate(Date date, Date dateBegin, Date dateEnd) {
        long startTime = dateBegin.getTime();
        long endTime = dateEnd.getTime();
        if (date.getTime() >= startTime && date.getTime() <= endTime) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 两个日期的 天数差
     * @return
     */
    public static int getDayGap(Date dateStart, Date dateEnd) {
        Calendar cStart = Calendar.getInstance();
        cStart.setTime(dateStart);
        cStart.set(Calendar.HOUR_OF_DAY, 0);
        dateStart = cStart.getTime();

        Calendar cEnd = Calendar.getInstance();
        cEnd.setTime(dateEnd);
        cEnd.set(Calendar.HOUR_OF_DAY, 0);
        dateEnd = cEnd.getTime();

        long start = dateStart.getTime() / (1000 * 3600 * 24);
        long end = dateEnd.getTime() / (1000 * 3600 * 24);
        return ((int) (end - start));
    }

    /**
     * 获取日期指定日期几天后的日期
     *
     * @return
     */
    public static Date getDateAfter(Date startDate, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(startDate);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    /**
     * 给日期添加小时
     *
     * @param date
     * @param hour
     * @return
     */
    public static Date getHoruAfter(Date date, int hour) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.add(Calendar.HOUR_OF_DAY, hour);
        return now.getTime();
    }

    /**
     * 获取日期指定日期几天前的日期
     *
     * @param startDate
     * @param day
     * @return
     */
    public static Date getDateBefore(Date startDate, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(startDate);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime();
    }

    /**
     * 返回星期几
     *
     * @param date
     * @return
     */
    public static int getWeek(Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        return now.get(Calendar.DAY_OF_WEEK) - 1;
    }

    public static void main(String[] args) {
        Date dateCheckIn = getYmdHmsDate("2017-12-12 23:59:59");// "yyyy-MM-dd HH:mm:ss";
        Date dateCheckOut = getYmdHmsDate("2017-12-13 1:01:01");
        System.out.println(getDayGap(dateCheckIn, dateCheckOut));

        long result = System.currentTimeMillis() + 30 * 60 * 1000;
        Date date = new Date(result);
        System.out.println(getDateStr(date));
    }

    // 从传入的日期减一秒
    public static Date subtractionMllisecond(Date date, int mill) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, mill);
        return calendar.getTime();
    }

    // 获取当前日期的星期一是几号
    public static Date dateMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(cal.DAY_OF_WEEK, cal.MONDAY);
        String dateFst = ymdFastFormat.format(cal.getTime());
        return getYmdDate(dateFst);
    }

    // 获取当前日期的星期日是几号
    public static Date dateSunday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(cal.DAY_OF_WEEK, cal.MONDAY);
        cal.set(Calendar.DATE, cal.get(cal.DATE) + 6);
        String dateFst = ymdFastFormat.format(cal.getTime());
        return getYmdDate(dateFst);
    }

    // 获取当前日期1号
    public static Date dateMonthFirst(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        date = c.getTime();
        return date;
    }

    // 获取当前日期月份的最后一天
    public static Date dateMonthLast(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        String lastday = ymdFastFormat.format(cale.getTime());
        return getYmdDate(lastday);
    }

    public static Date getCurrYearFirst(Date date) {
        Calendar currCal = Calendar.getInstance();
        currCal.setTime(date);
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 获取某年第一天日期
     *
     * @param year
     *            年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取当年的最后一天
     * @return
     */
    public static Date getCurrYearLast(Date date) {
        Calendar currCal = Calendar.getInstance();
        currCal.setTime(date);
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year
     *            年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    // 获取每周的星期一
    public static Date getNextWeekFirstDay(Date date, int i) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.WEEK_OF_MONTH, i);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return cal.getTime();
    }

    // 获取每周的星期日
    public static Date getNextWeekLastDay(Date date, int i) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.add(Calendar.WEEK_OF_MONTH, i);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return cal.getTime();
    }

    // 获取每月的1号
    public static Date getNextMonthFirstDay(Date date, int i) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, i);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return cale.getTime();
    }

    // 获取每月的最后一天
    public static Date getNextMonthLastDay(Date date, int i) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.add(Calendar.MONTH, i);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        return cale.getTime();
    }

    // 获取每月的最后一天
    public static Date getDayWithoutHM(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    /**
     *获取已经用了几天的假期，如果没有到开始日期，则返回0
     * @param start 开始日期
     * @param end 结束日期
     * @return
     */
    public static int getDay(Date start,Date end){
        Date date=new Date();
        if(date.getTime()<start.getTime()){
            return 0;
        }else if(end.getTime()<date.getTime()){
            return secondToDay(end.getTime()-start.getTime());
        }else if(date.getTime()<end.getTime()){
            return secondToDay(date.getTime()-start.getTime());
        }
        return 0;
    }

    //将毫秒数转成天数
    public static int secondToDay(long second){
        return (int)second/(24*60*60*1000)+1;
    }
}
